include(['com.unknown.Constants', 'com.unknown.Config', 'CanvasWrapper', 'constants.Screen', 'com.unknown.GameWindow'],

function(){

	declare('world.Entity');

    try{ world = world || {}; }
    catch(e){ world = {}; }

world.Entity = function(){

    var STILL = 0;
    var LEFT  = 1;
    var RIGHT = 2;
    var UP    = 4;
    var DOWN  = 8;

    var MAX_SPEED = 3;

    var FASTEST = 15;
    var NORMAL = 10;
    var SLOW = 5;
    var NOT_MOVING = 0;

    //String name;
	this.name = 'Player ' + Math.random();

    //EntityAttachment[] attachments;
    this.attachments = [];

	this.x = 16;
	this.y = 16;

	this.oldX = 16;
	this.oldY = 16;

	this.width = 50;
	this.height = 50;

	this.tmp = new Vector2(0,0);
	this.tmp2 = new Vector2(0,0);

	this.imageSeq = 0;
	this.imageIndex = 14;

	this._input  = new Vector2(0,0);
	this.cell = null;

       this.relativeCoord = null;

	this.inputChanged = function(input){
		input.x = input.x - (input.x % 3)
		input.y = input.y - (input.y % 3)

		if( this._input.x != input.x || this._input.y != input.y){

			this._input.reset(input.x, input.y);

               this.sendPositionUpdate();
		}
	};

    this.lastNetworkUpdate = 0;
    this.sendPositionUpdate = function(){
           if( !this.cell ) return;

           var position = this.cell.toLocalCoordinates(this.x, this.y);

           var update = {
               id : this.name
               ,vector : this._input
               ,roomId : this.cell.owner.roomId
               ,roomX : position.x
               ,roomY : position.y
           };

           bus.inputChanged(update);
    };

	this.determineDirection = function(){
		var dir = STILL;
		if( this._input.x > 5 ) dir = dir | RIGHT;
		if( this._input.x < -5 ) dir = dir | LEFT;
		if( this._input.y > 0 ) dir = dir | DOWN;
		if( this._input.y < 0 ) dir = dir | UP;
		return dir;
	};

	this.update = function(gamewindow){
		var vec = this._input;
		this.imageIndex--;
		if( this.imageIndex < 0 ){
			this.imageIndex = 14;
		}

		var moving = vec.x != 0 || vec.y != 0;
		if( !moving ){
			this.imageIndex = 16;
		}

		var dir = this.determineDirection();
		var previousSeq = this.imageSeq;
		if( !dir ){
			//DO Nothing
		}
		else if( (dir ^ (LEFT | UP)) == 0 )
			this.imageSeq = 1;
		else if( (dir ^ (LEFT | DOWN)) == 0 || (dir ^ (LEFT)) == 0 )
			this.imageSeq = 2;
		else if( (dir ^ (RIGHT | UP)) == 0 )
			this.imageSeq = 5;
		else if( (dir ^ (RIGHT | DOWN)) == 0 || (dir ^ (RIGHT)) == 0 )
			this.imageSeq = 3;
		else if( (dir ^ (DOWN)) == 0)
			this.imageSeq = 0;
		else if( (dir ^ (UP)) == 0)
			this.imageSeq = 4;
		else
			this.imageSeq = 1;

		this.x += Math.floor(Math.min(Math.abs(vec.x), MAX_SPEED) * (vec.x > 0 ? 1 : -1));
		this.y += Math.floor(Math.min(Math.abs(vec.y), MAX_SPEED) * (vec.y > 0 ? 1 : -1));

           if(moving && gamewindow.timestamp - this.lastNetworkUpdate > 2000){
               this.sendPositionUpdate();
               this.lastNetworkUpdate = gamewindow.timestamp;
           }
	};

	this.clearRect = function(){
		return {x:this.x, y:this.y-10, width:70, height:60};
	};

	this.render = function(gamewindow){
           if( this.relativeCoord ){
               var data = this.relativeCoord;
               this.cell.grid.node.toWorldCoordinate({x:data.x, y:data.y})
           }

		this.tmp.reset(this.x, this.y)
		var loc = gamewindow.normalize(this.tmp);

		var deltaX = 0;
		var deltaY = 0;

		var skip = this.skip;

		if( loc.x < this.x ){
			deltaX = (this.x - loc.x)+(skip || 0);
			this.x = loc.x - (skip || 0);
		}
		if( loc.y < this.y ){
			deltaY = (this.y - loc.y)+(skip || 0);
			this.y = loc.y - (skip || 0);
		}
		if( this.x < 20 ){
			deltaX = this.x-20+(skip || 0);
			this.x = 20 + (skip || 0);
		}
		if( this.y < 20 ){
			deltaY = (this.y)-20+(skip || 0);
			this.y = 20 + (skip || 0);
		}

		this.drawEntity(deltaX, deltaY, gamewindow);
	};
	this.drawEntity = function(deltaX, deltaY, gw){
           //I've got to clean this up and some point and move all of these
           //constants to an appropriate constant data structure (or data structures)
		var x = this.x;
		var y = Math.floor(this.y+this.height-10);

		var oldX = this.oldX;
		var oldY = this.oldY;

		var tile = room.getTile(x+25,y);
           this.cell = room.getCell(x+25,y);
		//if( tile ){
           //    this.cell = tile;

			gamewindow.c.font = '10px sans-serif';
			gamewindow.c.fillText(this.name, this.x+40, this.y);
            this._renderAttachments(gamewindow);

			var exit = tile && tile.roomid ? tile : null;
			if( exit ){
				gamewindow.c.font = '20px sans-serif';
				gamewindow.c.fillText(exit.name, this.x+70, this.y+40);
			}
			if( (deltaX || deltaY) && this == gw.player ){

                   eGrid.translate(-deltaX, -deltaY);
			}
		this.oldX = this.x;
		this.oldY = this.y;
	};

    this._renderAttachments = function(gamewindow){
        if( this.attachments ){
            var scope = this;
            iterate(this.attachments, function(attachment){
               attachment.render({entity:scope, gamewindow:gamewindow});

//                   if( img )
//                       gamewindow.draw(img, (scope.imageIndex + (scope.imageSeq*17)) * 100, 0, 100, 100, scope.x, scope.y, 100, 100);
            });
        }
    }

	this.activate = function(){
		var exit = room.getTile(this.x+25,Math.floor(this.y+this.height-10));
		if( exit.roomid ){
			room = new com.unknown.Room(roomUrl, exit.roomid, 'show');

			eGrid.reload();
		}
	};
};

});